import cloud from "@lafjs/cloud";
const db = cloud.database();
import { resultOk, checkPermission, resultFail, listToTree } from "@/utils";
const permissionName = "admin:menu";
const adminDbName = "menu";
const _ = db.command; // 这里拿到指令
interface Action {
  [key: string]: {
    method: string[];
    auth: boolean;
    permissions?: boolean;
    handler: Function;
  };
}

const menuItems = {
  name: "菜单名称", //菜单名称
  parentMenuId: "0", //上级目录
  type: "M", //菜单类型
  perms: "menu", //权限标识
  path: "menu", //路由地址
  isFrame: false, //外链
  isCache: false, //缓存
  sort: 0, //排序
  status: true, //是否启用
  visible: true, //是否显示
  component: "", //组件地址
  query: "", //路由参数
  remark: "", //备注
  createTime: new Date().getTime(), //创建时间
  editTime: new Date().getTime() //编辑时间
};
const actions: Action = {};
// 创建
actions.create = {
  method: ["POST"],
  auth: true,
  permissions: true,
  async handler(ctx: FunctionContext) {
    const body = ctx.body;
    if (
      (body.type === "C" && !body.path) ||
      (!body.component && body.type === "C")
    ) {
      return resultFail("数据不完整,请检查数据");
    }
    const items = Object.assign({}, menuItems, body);
    const { total: PermsTotal } = await db
      .collection(adminDbName)
      .where({
        perms: items.perms
      })
      .count();
    if (PermsTotal > 0) {
      return resultFail("权限已存在");
    }
    if (body.type !== "F") {
      const { total } = await db
        .collection(adminDbName)
        .where({ path: items.path })
        .count();
      if (total > 0) {
        return resultFail("路由已存在");
      }
    }
    const r = await db.collection(adminDbName).add(items);
    return resultOk(r);
  }
};
// 列表
actions.list = {
  method: ["POST"],
  auth: true,
  permissions: true,
  async handler(ctx: FunctionContext) {
    console.log(ctx, ">>>");
    // 数据库操作
    const db = cloud.database();
    const r = await db.collection(adminDbName).get();

    return resultOk({
      result: listToTree(
        r.data.map(_ => {
          _.id = _._id;
          _.children = [];
          return _;
        }),
        "id",
        "parentMenuId"
      )
    });
  }
};
// 删除
actions.delete = {
  method: ["POST"],
  auth: true,
  permissions: true,
  async handler(ctx: FunctionContext) {
    // check params
    const { id } = ctx.body;
    if (!id) {
      return resultFail("id不能为空");
    }

    // check id
    const { data: admin } = await db
      .collection(adminDbName)
      .where({ id })
      .getOne();
    if (!admin) {
      return resultFail("无此数据");
    }
    // delete
    const r = await db.collection(adminDbName).doc(id).remove();
    return resultOk(r);
  }
};
// 获取单个信息
actions.info = {
  method: ["POST"],
  auth: true,
  permissions: true,
  async handler(ctx: FunctionContext) {
    const { data: result } = await db
      .collection(adminDbName)
      .where({ _id: ctx.user.uid })
      .getOne();
    return resultOk({
      ...result
    });
  }
};
// 更新
actions.update = {
  method: ["POST"],
  auth: true,
  permissions: true,
  async handler(ctx: FunctionContext) {
    const body = ctx.body;
    if (
      !body.id ||
      (body.type === "C" && !body.path) ||
      (!body.component && body.type === "C")
    ) {
      return resultFail("数据不完整,请检查数据");
    }
    const items = Object.assign({}, menuItems, body);
    const { total: PermsTotal } = await db
      .collection(adminDbName)
      .where({
        perms: items.perms,
        _id: _.neq(body.id)
      })
      .count();
    if (PermsTotal > 0) {
      return resultFail("权限已存在");
    }
    if (body.type !== "F") {
      const { total } = await db
        .collection(adminDbName)
        .where({ path: items.path, _id: _.neq(body.id) })
        .count();
      if (total > 0) {
        return resultFail("路由已存在");
      }
    }
    delete items.id;
    delete items._id;
    delete items.children;
    delete items.createTime;
    const r = await db
      .collection(adminDbName)
      .where({ _id: body.id })
      .update({
        ...items,
        updated_at: new Date().getTime()
      });
    return resultOk(r);
  }
};

// 入口，拦截器
export default async function (ctx: FunctionContext) {
  const { action } = ctx.query;

  // 黑名单处理和访问频率处理，此处省去。见帖子：https://forum.laf.run/d/130/7
  // 顺便说一下，黑名单的处理可以放在`__interceptor__`中，这里仅处理频率问题即可。

  // 没有 action 或没找到 action 报错
  if (!action || !actions[action]) {
    return resultFail("请求失败");
  }

  const { method, auth, handler, permissions } = actions[action];

  // method 不符
  if (!method.includes(ctx.method)) {
    return resultFail("请求失败");
  }

  // 鉴权
  if (auth && ctx.user === null) {
    return resultFail("用户未登陆", -2);
  }

  if (
    permissions &&
    !checkPermission(ctx.user, `${permissionName}:${action}`)
  ) {
    return resultFail("未授权访问");
  }

  // 执行
  if (handler) {
    return await handler(ctx);
  }
  // 能执行到这里肯定哪儿写错了
  return resultFail("请求失败");
}
